{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 41,
   "id": "6793c985-a63c-4906-bbf7-293740b18b41",
   "metadata": {},
   "outputs": [],
   "source": [
    "import warnings\n",
    "warnings.filterwarnings(\"ignore\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9c794bc7",
   "metadata": {},
   "source": [
    "# 构建检索问答链"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f3d0f2c3-3bd9-4de1-bbd2-e0e2b09161c8",
   "metadata": {},
   "source": [
    "我们已经介绍了如何根据自己的本地知识文档，搭建一个向量知识库。 在接下来的内容里，我们将使用搭建好的向量数据库，对 query 查询问题进行召回，并将召回结果和 query 结合起来构建 prompt，输入到大模型中进行问答。   "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "95d8d968-8d98-47b9-8885-dc17d24dce76",
   "metadata": {},
   "source": [
    "## 1. 加载向量数据库\n",
    "\n",
    "首先，我们加载在前一章已经构建的向量数据库。注意，此处你需要使用和构建时相同的 Emedding。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "adc86262-da78-4fda-a597-600d54057062",
   "metadata": {},
   "source": [
    "### Milvus"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "d8349782-7ca4-4ebb-acc1-6097ff5cee99",
   "metadata": {},
   "outputs": [],
   "source": [
    "from langchain_community.vectorstores import Milvus\n",
    "# from langchain_milvus import MilvusVectorStore \n",
    "from langchain_community.embeddings import OllamaEmbeddings\n",
<<<<<<< HEAD
    "my_emb = OllamaEmbeddings(base_url='http://localhost:11434', model=\"bge-m3:latest\")\n",
=======
    "my_emb = OllamaEmbeddings(base_url='http://129.201.70.35:11434', model=\"dengcao/Qwen3-Embedding-0.6B:F16\")\n",
    "\n",
    "# from vllm import LLM\n",
    "# my_emb = LLM(\n",
    "#     model=\"/opt/workspace/models/Qwen/Qwen3-Embedding-0___6B\",\n",
    "#     task=\"embed\",\n",
    "#     enforce_eager=True,      # 避免可能的图优化问题\n",
    "#     dtype=\"float16\"          # 节省显存\n",
    "# )\n",
    "\n",
>>>>>>> b17ee39 (v0819)
    "\n",
    "# Milvus 连接参数\n",
    "vectordb = Milvus(\n",
    "        embedding_function=my_emb,\n",
    "        collection_name=\"ZXVMAXS\",  # Milvus 集合名称\n",
    "        connection_args={\n",
    "            \"host\": \"129.201.70.35\",  # Milvus 服务器地址\n",
    "            \"port\": \"19530\",  # Milvus 默认端口\n",
    "        },\n",
    "    )"
   ]
  },
  {
   "cell_type": "code",
<<<<<<< HEAD
   "execution_count": 5,
=======
   "execution_count": 12,
>>>>>>> b17ee39 (v0819)
   "id": "14c39416-a9b2-4de1-9fb6-5c521a7fd2f4",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
<<<<<<< HEAD
       "[Document(metadata={'pk': 460125151305459458, 'producer': 'Apache FOP Version 2.6', 'creator': 'DITA Open Toolkit', 'creationdate': '2023-05-23T21:45:33+08:00', 'source': '../data_base/knowledge_path/VMAX-S/ZXVMAX-S（V6.23）产品描述（上网日志业务）.pdf', 'file_path': '../data_base/knowledge_path/VMAX-S/ZXVMAX-S（V6.23）产品描述（上网日志业务）.pdf', 'total_pages': 29, 'format': 'PDF 1.4', 'title': '目录', 'author': '', 'subject': '', 'keywords': '', 'moddate': '', 'trapped': '', 'modDate': '', 'creationDate': \"D:20230523214533+08'00'\", 'page': 13}, page_content='4\\xa0功能本章包含如下主题：\\uf06c上网日志保存\\n10\\n\\uf06c上网日志查询\\n10\\n\\uf06c上网日志批量导入查询\\n11\\n\\uf06c日志管理\\n11\\n\\uf06c账号管理\\n11\\n\\uf06c角色管理\\n12\\n\\uf06c资源监控\\n12\\n\\uf06c告警管理\\n12\\n\\uf06c省级网关对接\\n12\\n\\uf06c拨测结果自动比对功能\\n12\\n\\uf06cNAT日志入库功能\\n13\\n\\uf06c北向接口\\n13\\n\\uf06c上网日志历史查询\\n13\\n\\uf06c云化上网日志XDR查询\\n13\\n以下介绍ZXVMAX-S的主要的功能。\\n4.1\\xa0上网日志保存\\uf06c支持使用Gbase数据库或HDFS保存上网日志。\\uf06c上网日志保存时间可配置，最短保存7天时间，最长可保存一年时间。\\uf06c支持自动清理超过保存时间的上网日志。\\n4.2\\xa0上网日志查询可通过web界面指定查询条件，查询用户上网日志。支持的查询条件：\\uf06c时间范围+公网IP\\n\\uf06c时间范围+目的IP\\n\\uf06c时间范围+MSISDN\\n\\uf06c时间范围+IMSI\\n\\uf06c时间范围+URL\\n\\uf06c支持组合以上五种基础条件，或在基础条件上增加指定公网端口、目的端口，做更精确的查询。\\n10\\nSJ-20220623151803-017|2023-03-30（R1.0）'),\n",
       " Document(metadata={'pk': 460125151305459460, 'producer': 'Apache FOP Version 2.6', 'creator': 'DITA Open Toolkit', 'creationdate': '2023-05-23T21:45:33+08:00', 'source': '../data_base/knowledge_path/VMAX-S/ZXVMAX-S（V6.23）产品描述（上网日志业务）.pdf', 'file_path': '../data_base/knowledge_path/VMAX-S/ZXVMAX-S（V6.23）产品描述（上网日志业务）.pdf', 'total_pages': 29, 'format': 'PDF 1.4', 'title': '目录', 'author': '', 'subject': '', 'keywords': '', 'moddate': '', 'trapped': '', 'modDate': '', 'creationDate': \"D:20230523214533+08'00'\", 'page': 14}, page_content='4.4\\xa0日志管理描述日志主要用户记录用户对IPDR系统的操作事件，是系统安全管理的重要组成部分。系统维护人员可通过web查看相关日志，对用户的操作进行追踪和审查。\\nZXVMAX-S提供对日志的查询、导出和下载功能。日志分类按照日志类型可以将日志分为三类：\\uf06c操作日志操作日志用户记录用户操作的详细信息，包括：操作时间、操作功能、操作结果、用户账号、主机地址、日志详细信息。操作日志包括新增、修改、删除等命令所记录下的日志信息。\\uf06c安全日志安全日志用来记录用户的登录和登出信息，包括：日志名称、用户账号、主机地址、操作时间、详细信息。\\uf06c系统日志系统日志用来记录系统运行时产生的日志，包括：主机、级别、时间、日志源、详细信息。\\n4.5\\xa0账号管理账号管理是系统安全管理最重要的组成部分，提供账号的创建、查询、修改、删除操作。创建账号时，可以指定用户名、密码、用户角色、用户联系方式，并为用户分配角色。通过分配不同角色，赋予用户不同的权限。提供账号策略和密码策略，达到安全保护的目的。\\nSJ-20220623151803-017|2023-03-30（R1.0）\\n11')]"
      ]
     },
     "execution_count": 5,
=======
       "[Document(metadata={'pk': 460219909630596817, 'producer': 'Apache FOP Version 2.3', 'creator': 'DITA Open Toolkit', 'creationdate': '2022-06-23T16:34:22+08:00', 'source': '../data_base/knowledge_path/VMAX-S/ZXVMAX-S（V6.20.80.02）告警处理.pdf', 'file_path': '../data_base/knowledge_path/VMAX-S/ZXVMAX-S（V6.20.80.02）告警处理.pdf', 'total_pages': 330, 'format': 'PDF 1.4', 'title': '目录', 'author': '', 'subject': '', 'keywords': '', 'moddate': '', 'trapped': '', 'modDate': '', 'creationDate': \"D:20220623163422+08'00'\", 'page': 281}, page_content='ZXVMAX-S多维价值分析系统告警处理可能原因确保实际填充率达到预期填充率处理步骤确保实际填充率达到预期填充率\\n7.1754000200259SGS接口MMEPort完整率(小时)告警描述确保实际填充率达到预期填充率告警级别警告可能原因确保实际填充率达到预期填充率处理步骤确保实际填充率达到预期填充率\\n7.1764000200260SGS接口MSCServerPort完整率(小时)告警描述确保实际填充率达到预期填充率告警级别警告可能原因确保实际填充率达到预期填充率处理步骤确保实际填充率达到预期填充率\\n7.1774000200261SGS接口ServiceIndicator完整率(小时)告警描述确保实际填充率达到预期填充率\\n260\\nSJ-20220623151803-011|2022-06-20（R1.0）'),\n",
       " Document(metadata={'pk': 460219909630596296, 'producer': 'Apache FOP Version 2.6', 'creator': 'DITA Open Toolkit', 'creationdate': '2023-09-14T10:39:24+08:00', 'source': '../data_base/knowledge_path/VMAX-S/ZXVMAX-S（V6.23）产品描述（5GC业务）.pdf', 'file_path': '../data_base/knowledge_path/VMAX-S/ZXVMAX-S（V6.23）产品描述（5GC业务）.pdf', 'total_pages': 42, 'format': 'PDF 1.4', 'title': '目录', 'author': '', 'subject': '', 'keywords': '', 'moddate': '', 'trapped': '', 'modDate': '', 'creationDate': \"D:20230914103924+08'00'\", 'page': 29}, page_content='ZXVMAX-S多维价值分析系统产品描述（5GC业务）图5-8会话跟踪组网逻辑图\\n26\\nSJ-20230406152852-016|2023-03-30（R1.0）')]"
      ]
     },
     "execution_count": 12,
>>>>>>> b17ee39 (v0819)
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "results = vectordb.similarity_search(query=\"什么是ZXVMAX-S的5GC业务？\", k=2)\n",
    "results"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4f7f8dbd-ecd5-449d-9753-aedc2b74289c",
   "metadata": {},
   "source": [
    "## 2. 创建一个 LLM"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "026bd74f-3dd0-496e-905b-950a444bb7a7",
   "metadata": {},
   "source": [
    "在这里，我们调用 OpenAI 的 API 创建一个 LLM，当然你也可以使用其他 LLM 的 API 进行创建"
   ]
  },
  {
   "cell_type": "code",
<<<<<<< HEAD
   "execution_count": 6,
   "id": "a89fb297-888a-4d35-b519-90eba639893c",
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/tmp/ipykernel_935149/307156435.py:3: LangChainDeprecationWarning: The class `Ollama` was deprecated in LangChain 0.3.1 and will be removed in 1.0.0. An updated version of the class exists in the :class:`~langchain-ollama package and should be used instead. To use it run `pip install -U :class:`~langchain-ollama` and import as `from :class:`~langchain_ollama import OllamaLLM``.\n",
      "  my_llm = Ollama(base_url='http://localhost:11434',\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "'<think>\\n\\n</think>\\n\\n你好！😊 有什么我可以帮助你的吗？'"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
=======
   "execution_count": 13,
   "id": "a89fb297-888a-4d35-b519-90eba639893c",
   "metadata": {},
   "outputs": [],
>>>>>>> b17ee39 (v0819)
   "source": [
    "# from langchain_community.llms import Ollama\n",
    "\n",
<<<<<<< HEAD
    "my_llm = Ollama(base_url='http://localhost:11434', \n",
    "                model='qwen3:8B', \n",
    "                temperature=0.1)\n",
    "\n",
    "my_llm.invoke(\"你好/no_think\")"
=======
    "# my_llm = Ollama(base_url='http://129.201.70.35:11434', model='qwen3:8B', temperature=0.1)\n",
    "\n",
    "# my_llm.invoke(\"你好\")\n",
    "\n",
    "from langchain_community.llms import VLLMOpenAI  # 注意类名为 VLLMOpenAI[3](@ref)\n",
    "llm = VLLMOpenAI(\n",
    "    openai_api_key=\"token-abc123\",          # vLLM 无需鉴权，设为空字符串[3](@ref)\n",
    "    openai_api_base=\"http://129.201.70.35:9991/v1\",  # 服务端地址\n",
    "    model_name=\"my_qwen3_8b\",  # 需与部署的模型路径一致\n",
    "    max_tokens=1024,                # 控制生成文本最大长度\n",
    "    temperature=0,               # 生成多样性参数（0~1）\n",
    "    top_p=0.9,                      # 采样阈值\n",
    "    streaming=True                  # 支持流式输出（可选）\n",
    ")"
>>>>>>> b17ee39 (v0819)
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8f361e27-cafb-48bf-bb41-50c9cb3a4f7e",
   "metadata": {},
   "source": [
    "## 3. 构建检索问答链"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "248b5e3c-1bc9-40e9-83c7-0594c2e7727d",
   "metadata": {},
   "source": [
    "prompts"
   ]
  },
  {
   "cell_type": "code",
<<<<<<< HEAD
   "execution_count": 7,
=======
   "execution_count": 14,
>>>>>>> b17ee39 (v0819)
   "id": "91be03f4-264d-45cb-bebd-223c1c5747fd",
   "metadata": {},
   "outputs": [],
   "source": [
    "from langchain.prompts import PromptTemplate\n",
    "\n",
    "template = \"\"\"你是VMAX运维助手，使用以下上下文来回答问题。如果你不知道答案，就说你不知道，不要试图编造答案。总是在回答的最后说“谢谢你的提问！”。\n",
    "{context}\n",
    "问题: {question}\n",
    "\"\"\"\n",
    "\n",
    "QA_CHAIN_PROMPT = PromptTemplate(input_variables=[\"context\",\"question\", \"sources\"],\n",
    "                                 template=template)\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e2d06d7f-1dca-4d10-b5cd-3a23e9d91200",
   "metadata": {},
   "source": [
    "#### 创建一个基于模板的检索链： 基础检索版本"
   ]
  },
  {
   "cell_type": "code",
<<<<<<< HEAD
   "execution_count": 8,
=======
   "execution_count": 15,
>>>>>>> b17ee39 (v0819)
   "id": "8b05eb57-edf5-4b35-9538-42c2b8f5cc16",
   "metadata": {},
   "outputs": [],
   "source": [
    "from langchain.chains import RetrievalQA\n",
    "\n",
    "# 基础检索\n",
    "base_retriever = vectordb.as_retriever(search_kwargs={\"k\": 10})\n",
    "base_retriever = vectordb.as_retriever(\n",
    "    search_kwargs={\"k\": 15},  # 扩大召回池\n",
    "    search_type=\"mmr\",  # 最大边际相关性算法（网页5）\n",
    "    # metadata_filter={\"source\": \"../data_base/knowledge_path/VMAX-S/ZXVMAX-S（V6.23）产品描述（5GC业务）.pdf\"}  # 元数据过滤\n",
    ")\n",
    "\n",
    "qa_chain = RetrievalQA.from_chain_type(my_llm,\n",
    "                                       retriever=base_retriever,\n",
    "                                       return_source_documents=True,\n",
    "                                       chain_type_kwargs={\"prompt\":QA_CHAIN_PROMPT})\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "503a7972-a673-41ca-a028-647169d19fcb",
   "metadata": {},
   "source": [
    "## 4.检索问答链效果测试"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "acc2223f-6fb5-4504-bfcd-ac74ca9ff2fa",
   "metadata": {},
   "source": [
    "### 4.1 基于召回结果和 query 结合起来构建的 prompt 效果"
   ]
  },
  {
   "cell_type": "code",
<<<<<<< HEAD
   "execution_count": 9,
=======
   "execution_count": 18,
>>>>>>> b17ee39 (v0819)
   "id": "fa1a61eb-feea-4fff-8063-a20c3b392aed",
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/tmp/ipykernel_935149/3076973797.py:2: LangChainDeprecationWarning: The method `Chain.__call__` was deprecated in langchain 0.1.0 and will be removed in 1.0. Use :meth:`~invoke` instead.\n",
      "  result = qa_chain({\"query\": question_1})\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "大模型+知识库后回答 question_1 的结果：\n",
      "<think>\n",
      "\n",
      "</think>\n",
      "\n",
<<<<<<< HEAD
      "ZXVMAX-S的5GC业务是指ZXVMAX-S多维价值分析系统针对5G核心网（5GC）场景所提供的网络运维和运营分析服务。该系统支持对5G网络中的各种业务和性能进行深入分析，包括但不限于网络质量分析、用户感知分析、问题根因定位、业务优化等。它能够帮助运营商实时监控和优化5G网络性能，提升用户体验，并为网络建设、运维优化和客户服务提供全面支撑。谢谢你的提问！\n"
=======
      "ZXVMAX-S的5GC业务是指ZXVMAX-S多维价值分析系统在5G核心网（5G Core Network, 5GC）场景中的应用。该系统面向用户的网络运维和运营分析，能够从网元、用户、终端、业务等多个维度，对业务使用过程中的质量和特征进行全方位的挖掘。它支持实时分析（如网络质量、数据业务质量等）和事后分析（如用户投诉、问题分析等），为移动通信网络的运维和运营提供全面支撑。\n",
      "\n",
      "ZXVMAX-S系统在5GC业务中，能够帮助运营商优化网络建设、提升运维效率，并挖掘用户数据价值，为互联网企业、银行、广告商、政府等单位提供行业应用支撑。\n",
      "\n",
      "谢谢你的提问！\n"
>>>>>>> b17ee39 (v0819)
     ]
    }
   ],
   "source": [
<<<<<<< HEAD
    "question_1 = \"什么是ZXVMAX-S的5GC业务？no_think\"\n",
=======
    "question_1 = \"什么是ZXVMAX-S的5GC业务？/no_think\"\n",
>>>>>>> b17ee39 (v0819)
    "result = qa_chain({\"query\": question_1})\n",
    "print(\"大模型+知识库后回答 question_1 的结果：\")\n",
    "print(result[\"result\"])\n",
    "# print(result[\"source_documents\"])"
   ]
  },
  {
   "cell_type": "code",
<<<<<<< HEAD
   "execution_count": 10,
=======
   "execution_count": 19,
>>>>>>> b17ee39 (v0819)
   "id": "2707095e-21d0-4e2b-8a5b-0c02258d2ce0",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "大模型+知识库后回答 question_2 的结果：\n",
      "<think>\n",
      "\n",
      "</think>\n",
      "\n",
<<<<<<< HEAD
      "我是一个AI助手，无法提供关于“严威”的具体信息。谢谢你的提问！\n"
=======
      "我目前的上下文信息中没有提到“严威”是谁，因此我无法提供相关信息。谢谢你的提问！\n"
>>>>>>> b17ee39 (v0819)
     ]
    }
   ],
   "source": [
<<<<<<< HEAD
    "question_2 = \"严威是谁？no_think\"\n",
=======
    "question_2 = \"严威是谁？/no_think\"\n",
>>>>>>> b17ee39 (v0819)
    "result = qa_chain({\"query\": question_2})\n",
    "print(\"大模型+知识库后回答 question_2 的结果：\")\n",
    "print(result[\"result\"])"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e4195cfa-1fc8-41a9-8984-91f2e5fbe013",
   "metadata": {},
   "source": [
    "### 4.2 无知识库大模型自己回答的效果"
   ]
  },
  {
   "cell_type": "code",
<<<<<<< HEAD
   "execution_count": 49,
=======
   "execution_count": 22,
>>>>>>> b17ee39 (v0819)
   "id": "569fbe28-2e2d-4042-b3a1-65326842bdc9",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
<<<<<<< HEAD
       "'<think>\\n\\n</think>\\n\\nZXVMAX-S 是华为推出的一款 5G 核心网（5GC）业务平台，主要用于提供 5G 网络中的核心网功能，支持多种 5G 业务场景。ZXVMAX-S 的全称是 **ZXVMAX-S 5G Core Business Platform**，它是一个基于云原生架构的 5G 核心网业务平台，旨在为运营商提供灵活、高效、可扩展的 5G 核心网解决方案。\\n\\n### ZXVMAX-S 的 5GC 业务主要包括以下内容：\\n\\n1. **5G 核心网功能支持**：\\n   - 支持 5G 网络中的关键功能模块，如 **AMF（接入和移动性管理功能）**、**SMF（会话管理功能）**、**UPF（用户面功能）**、**AUSF（认证服务器功能）**、**UDMF（统一数据管理功能）** 等。\\n   - 支持 5G 网络切片、网络能力开放、服务化架构（Service-Based Architecture, SBA）等。\\n\\n2. **多业务场景支持**：\\n   - 支持 eMBB（增强移动宽带）、URLLC（超可靠低时延通信）、mMTC（大规模机器类通信）等 5G 三大典型业务场景。\\n   - 支持 5G 与 4G/3G/2G 网络的互操作，实现多网络融合。\\n\\n3. **云原生架构**：\\n   - 基于云原生技术（如容器化、微服务、Kubernetes 等），实现灵活部署、弹性扩展和高可用性。\\n   - 支持 NFV（网络功能虚拟化）和 SDN（软件定义网络）技术，提升网络灵活性和智能化水平。\\n\\n4. **开放能力平台**：\\n   - 提供开放 API 接口，支持与第三方应用、行业应用、合作伙伴的对接，推动 5G 网络能力开放和生态建设。\\n   - 支持网络切片管理、业务链编排、网络自动化运维等功能。\\n\\n5. **安全与可靠性**：\\n   - 提供全面的安全机制，包括用户身份认证、数据加密、访问控制等，保障 5G 网络的安全性。\\n   - 支持高可用性架构，确保业务连续性和网络稳定性。\\n\\n### 总结：\\nZXVMAX-S 是华为面向 5G 核心网业务的综合解决方案，支持 5G 网络中的关键功能模块和多种业务场景，具备云原生架构、开放能力、高安全性和高可靠性，旨在帮助运营商构建灵活、高效、可扩展的 5G 核心网，满足未来智能社会的通信需求。'"
      ]
     },
     "execution_count": 49,
=======
       "'<think>\\n\\n</think>\\n\\nZXVMAX-S 是华为推出的一款面向5G网络的虚拟化核心网（5GC）解决方案，其全称是 **ZXVMAX-S 5G Core**。它是一种基于云原生架构的5G核心网业务平台，支持多种5GC业务功能，如：\\n\\n- **UE（用户设备）管理（AMF）**\\n- **会话管理（SMF）**\\n- **接入和移动性管理（AMF）**\\n- **策略控制（PCF）**\\n- **网络切片管理（NRF）**\\n- **统一数据管理（UDM）**\\n- **策略控制（PCF）**\\n- **服务化接口（NRF、NRM、Nnrf）**\\n\\n### ZXVMAX-S 的5GC业务特点：\\n\\n1. **云原生架构**：基于容器化、微服务架构，支持灵活扩展和高可用性。\\n2. **多业务支持**：支持多种5G业务场景，包括eMBB（增强移动宽带）、uRLLC（超可靠低时延通信）、mMTC（大规模机器类通信）等。\\n3. **开放接口**：支持与第三方业务平台、应用、网络切片管理平台等的对接。\\n4. **高可扩展性**：支持按需扩展，满足不同规模的运营商需求。\\n5. **支持网络切片**：支持5G网络切片的管理和调度，满足不同行业和场景的差异化需求。\\n6. **支持多厂商融合**：支持与不同厂商的5GC组件进行集成，实现多厂商融合部署。\\n\\n### 应用场景：\\n\\n- **智慧城市**：支持高密度连接和低时延通信。\\n- **工业互联网**：支持高可靠、低时延的工业控制。\\n- **车联网（V2X）**：支持高可靠、低时延的车联网通信。\\n- **远程医疗**：支持高带宽、低时延的远程手术和诊断。\\n- **AR/VR**：支持高带宽、低时延的沉浸式体验。\\n\\n### 总结：\\n\\nZXVMAX-S 的5GC业务是华为面向5G时代推出的核心网解决方案，支持多种5GC功能和业务场景，具备高可扩展性、开放性和灵活性，适用于多种行业和应用场景，是构建5G网络的重要基础设施。'"
      ]
     },
     "execution_count": 22,
>>>>>>> b17ee39 (v0819)
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "prompt_template = \"\"\"请回答下列问题:\n",
    "                            {}\"\"\".format(question_1)\n",
    "\n",
    "### 基于大模型的问答\n",
    "my_llm.predict(prompt_template)"
   ]
  },
  {
   "cell_type": "code",
<<<<<<< HEAD
   "execution_count": 50,
=======
   "execution_count": 21,
>>>>>>> b17ee39 (v0819)
   "id": "d0d3a813-db19-4be5-8926-ad8298e3e2b1",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
<<<<<<< HEAD
       "'<think>\\n\\n</think>\\n\\n“严威”是一个常见的中文名字，可能指不同领域的人。以下是几种可能的解释：\\n\\n1. **历史人物**：  \\n   严威是东汉时期的人物，字子高，是严光（即严子陵）的弟弟。严光是东汉开国功臣刘秀的故交，以隐士著称。严威在历史上记载较少，但可能与严光有某种关联。\\n\\n2. **现代人物**：  \\n   - **严威（演员）**：中国内地男演员，参演过《大宅门》《新三国》等电视剧。  \\n   - **严威（作家/学者）**：可能指某些学者或作家，但需要更多背景信息确认。  \\n   - **其他领域**：可能指企业高管、运动员等，但需具体上下文。\\n\\n3. **其他可能性**：  \\n   - 可能是某个地方的名人、家族成员，或网络上的昵称。\\n\\n**总结**：  \\n若需准确回答“严威是谁”，需要更多上下文（如领域、时代、相关事件等）。若指历史人物，可能与东汉严光有关；若指现代人物，可能是演员或学者。建议补充信息以进一步确认。'"
      ]
     },
     "execution_count": 50,
=======
       "'<think>\\n\\n</think>\\n\\n“严威”是一个常见的中文名字，可能指代不同领域中的不同人物。以下是几种可能的解释：\\n\\n1. **历史人物**：  \\n   在中国历史中，“严威”并非一个广为人知的专有名词，但“严”姓在历史上有几位著名人物，如东汉的严光（严子陵），但“严威”并非其名。\\n\\n2. **现代人物**：  \\n   - **严威（演员）**：中国内地男演员，曾参演多部影视剧，如《新还珠格格》《巴啦啦小魔仙》等。  \\n   - **严威（作家/学者）**：可能指某些学者或作家，但具体信息需结合上下文进一步确认。\\n\\n3. **其他领域**：  \\n   - 在企业、学术界或艺术界，可能有名为“严威”的人士，但需更多背景信息才能准确识别。\\n\\n**总结**：  \\n若需更准确的回答，请提供更多上下文（如领域、相关事件等）。目前“严威”可能指演员、学者或其他领域的人物，但无明确指向性。'"
      ]
     },
     "execution_count": 21,
>>>>>>> b17ee39 (v0819)
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "prompt_template = \"\"\"请回答下列问题:\n",
    "                            {}\"\"\".format(question_2)\n",
    "\n",
    "### 基于大模型的问答\n",
    "my_llm.predict(prompt_template)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "51b9ba4a-053d-409a-a632-63336c2bdf84",
   "metadata": {},
   "source": [
    "> ⭐ 通过以上两个问题，我们发现 LLM 对于一些近几年的知识以及非常识性的专业问题，回答的并不是很好。而加上我们的本地知识，就可以帮助 LLM 做出更好的回答。另外，也有助于缓解大模型的“幻觉”问题。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ce0fee88-5d13-43dd-9415-180d9e6bf2e7",
   "metadata": {},
   "source": [
    "## 5. 添加历史对话的记忆功能"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "69e633b4-879d-4e67-8f3e-d5c82f1712c3",
   "metadata": {},
   "source": [
    "现在我们已经实现了通过上传本地知识文档，然后将他们保存到向量知识库，通过将查询问题与向量知识库的召回结果进行结合输入到 LLM 中，我们就得到了一个相比于直接让 LLM 回答要好得多的结果。在与语言模型交互时，你可能已经注意到一个关键问题 - **它们并不记得你之前的交流内容**。这在我们构建一些应用程序（如聊天机器人）的时候，带来了很大的挑战，使得对话似乎缺乏真正的连续性。这个问题该如何解决呢？\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e41cc4ec-5b42-4c8c-aafc-65745c9e59b2",
   "metadata": {},
   "source": [
    "### 5.1 记忆（Memory）"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "fc053f6c-aeed-42b9-938a-2c52020f1327",
   "metadata": {},
   "source": [
    "在本节中我们将介绍 LangChain 中的储存模块，即如何将先前的对话嵌入到语言模型中的，使其具有连续对话的能力。我们将使用 `ConversationBufferMemory` ，它保存聊天消息历史记录的列表，这些历史记录将在回答问题时与问题一起传递给聊天机器人，从而将它们添加到上下文中。"
   ]
  },
  {
   "cell_type": "code",
<<<<<<< HEAD
   "execution_count": 38,
   "id": "e2ed5b18-1bd6-4160-b68e-4300ccc5d4b3",
   "metadata": {},
   "outputs": [],
=======
   "execution_count": 23,
   "id": "e2ed5b18-1bd6-4160-b68e-4300ccc5d4b3",
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/tmp/ipykernel_8051/2228008247.py:3: LangChainDeprecationWarning: Please see the migration guide at: https://python.langchain.com/docs/versions/migrating_memory/\n",
      "  memory = ConversationBufferMemory(\n"
     ]
    }
   ],
>>>>>>> b17ee39 (v0819)
   "source": [
    "from langchain.memory import ConversationBufferMemory\n",
    "\n",
    "memory = ConversationBufferMemory(\n",
    "    memory_key=\"chat_history\",  # 与 prompt 的输入变量保持一致。\n",
    "    return_messages=True  # 将以消息列表的形式返回聊天记录，而不是单个字符串\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b1d2c797-5706-438c-ae11-bf4aa81795ba",
   "metadata": {},
   "source": [
    "关于更多的 Memory 的使用，包括保留指定对话轮数、保存指定 token 数量、保存历史对话的总结摘要等内容，请参考 langchain 的 Memory 部分的相关文档。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b56fe278-2109-4b7b-9604-2ea030b18caa",
   "metadata": {},
   "source": [
    "### 5.2 对话检索链（ConversationalRetrievalChain）"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "76abe746-8e01-4067-9675-354deecdfde7",
   "metadata": {},
   "source": [
    "对话检索链（ConversationalRetrievalChain）在检索 QA 链的基础上，增加了处理对话历史的能力。\n",
    "\n",
    "它的工作流程是:\n",
    "1. 将之前的对话与新问题合并生成一个完整的查询语句。\n",
    "2. 在向量数据库中搜索该查询的相关文档。\n",
    "3. 获取结果后,存储所有答案到对话记忆区。\n",
    "4. 用户可在 UI 中查看完整的对话流程。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "fd98d830-0f2f-4794-acc2-4c23428bdd8c",
   "metadata": {},
   "source": [
    "这种链式方式将新问题放在之前对话的语境中进行检索，可以处理依赖历史信息的查询。并保留所有信\n",
    "息在对话记忆中，方便追踪。\n",
    "\n",
    "接下来让我们可以测试这个对话检索链的效果："
   ]
  },
  {
   "cell_type": "code",
<<<<<<< HEAD
   "execution_count": 39,
=======
   "execution_count": 24,
>>>>>>> b17ee39 (v0819)
   "id": "a4ba5ed5-24c4-4725-be2f-5d24bfbdee89",
   "metadata": {},
   "outputs": [],
   "source": [
    "from langchain.prompts import PromptTemplate\n",
    "from langchain.chains import ConversationalRetrievalChain\n",
    "# 修改后的Prompt模板（添加chat_history变量）\n",
    "template = \"\"\"你是VMAX运维助手，请参考以下对话历史和上下文来回答问题：\n",
    "    {chat_history}\n",
    "    \n",
    "    相关上下文：\n",
    "    {context}\n",
    "    \n",
    "    问题：{question}\n",
    "    回答结束时说“谢谢你的提问！”\n",
    "    \"\"\"\n",
    "    \n",
    "QA_PROMPT = PromptTemplate(\n",
    "        input_variables=[\"chat_history\", \"context\", \"question\"],\n",
    "        template=template\n",
    "    )\n",
    "    \n",
    "# 创建对话链\n",
    "qa_chain = ConversationalRetrievalChain.from_llm(\n",
    "        llm=my_llm,\n",
    "        retriever=vectordb.as_retriever(),\n",
    "        memory=memory,\n",
    "        combine_docs_chain_kwargs={\"prompt\": QA_PROMPT},\n",
    "        chain_type=\"stuff\"\n",
    "    )\n",
    "    \n",
    "    # result = qa_chain({\"question\": question})\n",
    "    # return result[\"answer\"]\n",
    "    "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "id": "2e96fbc6-935e-40ac-81b5-3a220fe05741",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "回答：<think>\n",
      "\n",
      "</think>\n",
      "\n",
      "ZXVMAX-S的5GC业务是指ZXVMAX-S多维价值分析系统针对5G核心网（5GC）场景所提供的网络运维和运营分析服务。该系统能够支持5G网络中的信令采集、数据存储、分析处理以及多维度的业务洞察，帮助运营商实现对5G网络质量、用户行为、终端性能、业务特征等方面的全面分析和优化。ZXVMAX-S在5GC业务中，能够支持实时分析和事后分析两种模式，为5G网络的运维和运营提供全面支撑。\n",
      "\n",
      "谢谢你的提问！\n",
      "\n",
      "==================================================\n",
      "\n",
      "回答：<think>\n",
      "\n",
      "</think>\n",
      "\n",
      "ZXVMAX-S的5GC业务包含以下主要功能：\n",
      "\n",
      "1. **一键投诉功能**  \n",
      "   输入用户号码或IMSI以及投诉的起止时间，系统可以快速定位引起用户投诉的具体问题业务记录（即问题话单），并分析导致问题发生的原因，包括4G、5G无线、核心网、SP以及用户等因素。\n",
      "\n",
      "2. **区域感知功能**  \n",
      "   定期（支持天/周/月粒度）对全网的所有小区进行排查，识别感知较差的小区，并分析导致这些小区用户感知差的原因，涵盖4G、5G无线、核心网、SP以及用户等因素。同时支持对事先配置的重点区域进行感知分析，包括感知评估和根因定位。\n",
      "\n",
      "3. **用户感知功能**  \n",
      "   定期（支持天/周/月粒度）对全网的所有用户进行排查，识别感知较差的用户，并分析导致这些用户感知差的原因，涵盖4G、5G无线、核心网、SP以及用户等因素。同时支持对事先配置的VIP用户进行感知分析，包括感知评估和根因定位。\n",
      "\n",
      "4. **实时分析与事后分析**  \n",
      "   ZXVMAX-S支持两种分析模式：  \n",
      "   - **实时分析**：用于网络质量、数据业务质量等的实时监控和分析。  \n",
      "   - **事后分析**：用于用户投诉、问题分析等场景的深度挖掘和根因定位。\n",
      "\n",
      "5. **多维度分析能力**  \n",
      "   系统能够从网元、用户、终端、业务等多个维度对网络和业务信息进行全方位分析，支持性能优化、事件处理、用户分析、终端分析、业务优化等业务功能。\n",
      "\n",
      "6. **灵活的数据查询与分析**  \n",
      "   支持根据用户需求进行数据自定义查询或分析，满足不同场景下的分析需求。\n",
      "\n",
      "这些功能共同支撑了5G核心网（5GC）的运维和运营分析，帮助运营商提升网络质量、优化用户体验，并挖掘数据价值。\n",
      "\n",
      "谢谢你的提问！\n",
      "\n",
      "==================================================\n",
      "\n",
      "回答：<think>\n",
      "\n",
      "</think>\n",
      "\n",
      "| 功能模块 | 功能描述 |\n",
      "|----------|----------|\n",
      "| 用户分析功能 | 支持对用户进行感知分析，识别感知较差的用户，并分析导致用户感知差的原因，涵盖4G、5G无线、核心网、SP以及用户等因素。 |\n",
      "| 网络分析功能 | 支持对全网的所有小区进行排查，识别感知较差的小区，并分析导致这些小区用户感知差的原因，涵盖4G、5G无线、核心网、SP以及用户等因素。 |\n",
      "| 专题分析功能 | 支持对事先配置的重点区域或VIP用户进行感知分析，包括感知评估和根因定位。 |\n",
      "| 评估优化功能 | 提供网络质量、用户感知等方面的评估和优化建议，帮助运营商提升网络性能和用户体验。 |\n",
      "| 可维可测功能 | 支持实时分析和事后分析两种模式，用于网络质量、数据业务质量等的监控和分析。 |\n",
      "| 咨询服务业务 | 提供专业的运维和运营咨询服务，支持数据查询、分析和定制化需求。 |\n",
      "| 维护保障业务 | 通过多维度分析能力，支持性能优化、事件处理、用户分析、终端分析、业务优化等运维保障功能。 |\n",
      "\n",
      "谢谢你的提问！\n",
      "\n",
      "==================================================\n",
      "\n"
     ]
    }
   ],
   "source": [
    "questions = [\n",
    "    \"什么是ZXVMAX-S的5GC业务？no_think\",\n",
    "    \"包含哪些功能no_think\", \n",
    "    \"整理成表格no_think\"  \n",
    "]\n",
    "\n",
    "for question in questions:\n",
    "    result = qa_chain({\"question\": question})  # Pass string directly, not dict\n",
    "    # print(f\"问题：{question}\")\n",
    "    print(f\"回答：{result['answer']}\")\n",
    "    # print(\"对话历史：\", memory.load_memory_variables({}))\n",
    "    print(\"\\n\" + \"=\"*50 + \"\\n\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "b62782f0-a996-4461-af2e-3fa4ce304c59",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python3 (env_rag)",
   "language": "python",
   "name": "env_rag"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.12.11"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
